package com.xuliugen.rocketmq.springboot.starter.consumer.annotation;

import com.xuliugen.rocketmq.springboot.starter.consumer.common.enums.ConsumeMode;
import com.xuliugen.rocketmq.springboot.starter.consumer.common.enums.SelectorType;
import org.apache.rocketmq.common.filter.ExpressionType;
import org.apache.rocketmq.common.protocol.heartbeat.MessageModel;

import java.lang.annotation.*;

/**
 * 用于RocketMQListener实现类上的注解，用于设置topic、consumerGroup等参数，示例如下：
 * <pre class="code">
 * @Slf4j
 * @Service
 * @RocketMQMessageListener(topic = "test-topic-2", consumerGroup = "my-consumer_test-topic-2")
 * public class MyConsumer implements RocketMQListener<OrderPaidEvent>{
 *     public void onMessage(OrderPaidEvent orderPaidEvent) {
 *         log.info("received orderPaidEvent: {}", orderPaidEvent);
 *     }
 * }
 * </pre>
 * @author xuliugen
 */
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface RocketMQMessageListener {

    /**
     * Consumers of the same role is required to have exactly same subscriptions and consumerGroup to correctly achieve
     * load balance. It's required and needs to be globally unique.
     * <p>
     * </p>
     * See <a href="http://rocketmq.apache.org/docs/core-concept/">here</a> for further discussion.
     */
    String consumerGroup();

    /**
     * Topic name
     */
    String topic();

    /**
     * Control how to selector message
     * @see ExpressionType
     */
    SelectorType selectorType() default SelectorType.TAG;

    /**
     * Control which message can be select. Grammar please see {@link ExpressionType#TAG} and {@link ExpressionType#SQL92}
     */
    String selectorExpress() default "*";

    /**
     * Control consume mode, you can choice receive message concurrently or orderly
     */
    ConsumeMode consumeMode() default ConsumeMode.CONCURRENTLY;

    /**
     * Control message mode, if you want all subscribers receive message all message, broadcasting is a good choice.
     */
    MessageModel messageModel() default MessageModel.CLUSTERING;

    /**
     * Max consumer thread number
     */
    int consumeThreadMax() default 64;
}
